package com.ruoyi.project.system.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.SmIncome;
import com.ruoyi.project.system.domain.SmPay;
import com.ruoyi.project.system.domain.SmProduct;
import com.ruoyi.project.system.domain.vo.PayVo;
import com.ruoyi.project.system.mapper.SmIncomeMapper;
import com.ruoyi.project.system.mapper.SmPayMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.ISmPayService;
import com.ruoyi.project.system.service.ISmProductService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.ruoyi.common.constant.CacheConstants.UPGRADE_KICKBACK;
import static com.ruoyi.framework.web.domain.AjaxResult.error;
import static com.ruoyi.framework.web.domain.AjaxResult.success;

/**
 * 支付Service业务层处理
 */
@Slf4j
@Service
public class SmPayServiceImpl implements ISmPayService {

    @Autowired
    private ISmProductService iSmProductService;

    @Autowired
    private SmPayMapper smPayMapper;

    @Autowired
    private SmIncomeMapper smIncomeMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RedisCache redisCache;

    @Value("${back-domain}")
    private String backDomain;

    @Value("${front-domain}")
    private String frontDomain;

    @Override
    public JSONObject zhifuFM(SmPay sm, String path) throws IOException {
        //      容易查
        String merchantNum = "1394150425178931200";             // 商户号
        String secretKey = "086951d2cdb0b467c553b507d6f866db";  // 商户密钥
        String sign = merchantNum + sm.getOrderNo() + sm.getPricing() + backDomain + secretKey;
        sign = Md5Utils.hash(sign);                             // md5签名
        Map<String, String> paramMap = new HashMap<>();         // post请求的参数
        paramMap.put("merchantNum", merchantNum);
        paramMap.put("orderNo", sm.getOrderNo());
        paramMap.put("amount", sm.getPricing().toString());
        paramMap.put("notifyUrl", backDomain);     // 填写您的接收支付成功的异步通知地址
        paramMap.put("returnUrl", frontDomain + path);
        paramMap.put("payType", sm.getPayType());  // MGZ TODO 2025/3/25:支付方式
        paramMap.put("sign", sign);
        paramMap.put("subject", sm.getType());
        log.info("支付请求参数：" + paramMap);
        String result;
        JSONObject ret = new JSONObject();
        String paramStr = StringUtils.toParams(paramMap);
        CloseableHttpClient httpclient = HttpClientBuilder.create().build();
        HttpPost httpost = new HttpPost("http://api-albd2vor5wqo.zhifu.fm.it88168.com/api/startOrder?" + paramStr); // 设置响应头信息
        String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36";
        httpost.setHeader("User-Agent", userAgent);     //防止被防火墙拦截 Apache httpclient
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(1000).setSocketTimeout(5000).build();
        httpost.setConfig(requestConfig);

//        if (1 == 1) { // MGZ TODO 2025/5/23:发起支付测试
//            return JSONObject.parseObject("{\"success\":true,\"msg\":\"success\",\"code\":200,\"timestamp\":1742923519942,\"data\":{\"id\":\"498753173364817920\",\"payUrl\":\"https://page-albd2vor5wqo.zhifu.fm.it88168.com/apiPay?orderNo=" + sm.getOrderNo() + "\"}}");
//        }

        HttpResponse retResp = httpclient.execute(httpost);
        result = EntityUtils.toString(retResp.getEntity(), "UTF-8");
        if (result.startsWith("{")) { //为了您的业务健壮性，建议简单判断或者增加下容错逻辑
            ret = JSONObject.parseObject(result);
        } else {
            ret.put("code", "error");
            ret.put("result", result);
            ret.put("msg", "发起支付订单失败，接口返回信息异常");
        }
        return ret;
    }

    @Override
    public AjaxResult upgradePay(SmPay smPay) {
        // 1. 写入支付订单
        this.insertSmPay(smPay);
        // 2. 计算写入分成
        this.calculateUpgradeIncome(smPay);
        // 3. 发起支付
        try {
            JSONObject payInfo = this.zhifuFM(smPay, "index");
            payInfo.put("orderNo", smPay.getOrderNo());
            return success(payInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return error("发起支付异常！");
        }
    }

    public float platformRevenue(float userBasePrice, float promotionAdd) {
        float pricing = userBasePrice + promotionAdd;
        if (pricing <= 30) {
            return promotionAdd;
        } else if (pricing <= 90f) {
            if (userBasePrice <= 30f) {
                return promotionAdd - (pricing - 30f) * 0.08f;
            }
            return promotionAdd - (pricing - userBasePrice) * 0.08f;
        } else if (pricing <= 120f) {
            if (userBasePrice <= 90f) {
                return promotionAdd - (pricing - 30f) * 0.09f;
            }
            return promotionAdd - (pricing - userBasePrice) * 0.09f;
        } else {
            if (userBasePrice <= 120f) {
                return promotionAdd - (pricing - 30f) * 0.1f;
            }
            return promotionAdd - (pricing - userBasePrice) * 0.1f;
        }
    }

    @Override
    public void calculatePromotionIncome(SmPay smPay, Integer roleId, SmProduct smProduct) {            // MGZ TODO 2025/4/12:计算查询收益
        // 自己收益
        BigDecimal userBasePrice = iSmProductService.userBasePrice(smPay.getUserId(), roleId, smProduct);

        BigDecimal promotionAdd = iSmProductService.promotionAdd(smPay.getUserId(), smProduct);

        float promotion = platformRevenue(userBasePrice.floatValue(), promotionAdd.floatValue());

        smIncomeMapper.insertSmIncome(new SmIncome(smPay.getUserId(), "1", "自己推广收益", BigDecimal.valueOf(promotion), smPay, "promotion"));
        calculateCommonIncome(smPay, roleId, smProduct);
    }

    @Override
    public void calculateCommonIncome(SmPay smPay, Integer roleId, SmProduct smProduct) {
        if (roleId == 1 || roleId == 2 || roleId == 5) {
            return;
        }
        Long parentId = sysUserMapper.queryParentId(smPay.getUserId());
        if (parentId == null) {
            return;
        }
        String type = "使用" + smProduct.getName() + "分润";
        if (roleId == 3) {         // 普通代理使用 (总代理收益)

            BigDecimal userBasePrice = iSmProductService.userBasePrice(parentId, 2, smProduct);

            BigDecimal basePriceAdd = iSmProductService.basePriceAdd(parentId, smProduct);

            float promotion = platformRevenue(userBasePrice.floatValue(), basePriceAdd.floatValue());

            smIncomeMapper.insertSmIncome(new SmIncome(
                    parentId, "1", "普通代理" + type, BigDecimal.valueOf(promotion), smPay, "captain-region")
            );
        } else if (roleId == 4) {  // 代理下级使用 (普通代理/总代理收益)

            Integer roleId_ = sysUserMapper.queryRoleId(parentId);

            String n = "代理下级";
            if (roleId_ == 3) {
                BigDecimal userBasePrice = iSmProductService.userBasePrice(parentId, 3, smProduct);
                BigDecimal basePriceAdd = iSmProductService.basePriceAdd(parentId, smProduct);
                float promotion = platformRevenue(userBasePrice.floatValue(), basePriceAdd.floatValue());
                smIncomeMapper.insertSmIncome(new SmIncome(
                        parentId, "1", "代理下级" + type, BigDecimal.valueOf(promotion), smPay, "member-captain")
                );
                n = "普通代理";
                parentId = sysUserMapper.queryParentId(parentId);
            }
            if (parentId == null) {
                return;
            }
            BigDecimal userBasePrice_ = iSmProductService.userBasePrice(parentId, 2, smProduct);
            BigDecimal basePriceAdd_ = iSmProductService.basePriceAdd(parentId, smProduct);
            float promotion_ = platformRevenue(userBasePrice_.floatValue(), basePriceAdd_.floatValue());
            smIncomeMapper.insertSmIncome(new SmIncome(
                    parentId, "1", n + type, BigDecimal.valueOf(promotion_), smPay, "member-region")
            );

            smIncomeMapper.insertSmIncome(new SmIncome(
                    parentId, "1", "平台额外补贴", BigDecimal.valueOf(2f), smPay, "平台额外补贴总代理")
            );
        }
    }

    public void calculateUpgradeIncome(SmPay smPay) {
        Long userId = smPay.getUserId();
        BigDecimal kickback = redisCache.getCacheObject(UPGRADE_KICKBACK + smPay.getRemark());
        BigDecimal income = null;
        Long parentId = null;
        String upgradePath = smPay.getRemark();
        String upgrade = SecurityUtils.getUsername() + "升级";
//        String[] targetPath = smPay.getRemark().split("->");
//        String source = targetPath[0];
//        String target = targetPath[1];
        if ("ordinary->member".equals(upgradePath)) {           // 1. 普通账户 —> 队员
            // upgrade_kickback:ordinary->member
            return;
        } else if ("ordinary->captain".equals(upgradePath)) {   // 2. 普通账户 —> 队长
            // upgrade_kickback:ordinary->captain
            return;
        } else if ("ordinary->region".equals(upgradePath)) {    // 2. 普通账户 —> 区域队长
            // upgrade_kickback:ordinary->region
            return;
        } else if ("member->captain".equals(upgradePath)) {     // 3. 队员 —> 队长
            // upgrade_kickback:member->captain
            //  队员给予上级队长补偿费用
            upgrade += "（队员—>队长）";
            income = smPay.getPricing().multiply(kickback);
            parentId = sysUserMapper.queryParentId(userId);
            if (parentId == null)
                return;
        } else if ("member->region".equals(upgradePath)) {      // 4. 队员 —> 区域队长
            // upgrade_kickback:member->region
            // 队员给予上级区域队长补偿费用
            upgrade += "（队员—>区域队长）";
            income = smPay.getPricing().multiply(kickback);
            parentId = sysUserMapper.queryParentId(userId);
            if (parentId == null)
                return;
        } else if ("captain->region".equals(upgradePath)) {     // 5. 队长 —> 区域队长
            // upgrade_kickback:captain->region
            // 队长给予上级区域队长补偿费用
            upgrade += "（队长—>区域队长）";
            income = smPay.getPricing().multiply(kickback);
            parentId = sysUserMapper.queryParentId(userId);
            if (parentId == null)
                return;
        }

        smIncomeMapper.insertSmIncome(new SmIncome(parentId, "1", upgrade, income, smPay, "upgrade"));
    }

    @Override
    @Transactional
    public void paySuccessUpgradeSetUser(SmPay smPay) {
        String target = smPay.getRemark().split("->")[1];
        Integer roleId;
        if ("member".equals(target)) {           // 1. —> 队员
            roleId = 4;
        } else if ("captain".equals(target)) {   // 2. —> 队长
            roleId = 3;
        } else if ("region".equals(target)) {    // 2. —> 区域队长
            roleId = 2;
        } else {
            log.error("升级异常!");
            return;
        }
        long userId = smPay.getUserId().longValue();

    }

    /**
     * 查询支付
     *
     * @param id 支付主键
     * @return 支付
     */
    @Override
    public SmPay selectSmPayById(Integer id) {
        return smPayMapper.selectSmPayById(id);
    }

    /**
     * 查询支付列表
     *
     * @param payVo 支付
     * @return 支付
     */
    @Override
    public List<PayVo> selectSmPayList(PayVo payVo) {
        return smPayMapper.selectSmPayList(payVo);
    }

    /**
     * 新增支付
     *
     * @param smPay 支付
     * @return 结果
     */
    @Override
    public int insertSmPay(SmPay smPay) {
        smPay.setCreateTime(DateUtils.getNowDate());
        return smPayMapper.insertSmPay(smPay);
    }

    /**
     * 修改支付
     *
     * @param smPay 支付
     * @return 结果
     */
    @Override
    public int updateSmPay(SmPay smPay) {
        smPay.setUpdateTime(DateUtils.getNowDate());
        return smPayMapper.updateSmPay(smPay);
    }

    /**
     * 批量删除支付
     *
     * @param ids 需要删除的支付主键
     * @return 结果
     */
    @Override
    public int deleteSmPayByIds(Integer[] ids) {
        return smPayMapper.deleteSmPayByIds(ids);
    }
}
